#include "fepch.h"
#include "EditorUI.h"

#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl3.h"
#include "backends/imgui_impl_opengl3_loader.h"

#include "FysicsEngine/Application.h"

namespace Fysics
{
	bool EditorUI::NewMenu(const char* menuName, float width, float height,
		bool showTitle, bool canChangeSize, bool* closebtn)
	{
		ImGuiWindowFlags windowflags = 0;
		if (!showTitle)
			windowflags |= ImGuiWindowFlags_NoTitleBar;
		if (!canChangeSize)
			windowflags |= ImGuiWindowFlags_NoResize;

		if (width >= 0 && height >= 0)
			ImGui::SetNextWindowSize(ImVec2(width, height));
		return ImGui::Begin(menuName, closebtn, windowflags);
	}

	bool EditorUI::NewMenu(const char* menuName, float width, float height, float x, float y,
		bool showTitle, bool canChangeSize, bool* closebtn)
	{
		ImGuiWindowFlags windowflags = 0;
		if (!showTitle)
			windowflags |= ImGuiWindowFlags_NoTitleBar;
		if (!canChangeSize)
			windowflags |= ImGuiWindowFlags_NoResize;

		if (width >= 0 && height >= 0)
			ImGui::SetNextWindowSize(ImVec2(width, height));
		
		ImGuiViewport* viewport = ImGui::GetMainViewport();
		ImVec2 pos = viewport->WorkPos;
		pos.x += x;
		pos.y += y;
		ImGui::SetNextWindowPos(pos);

		return ImGui::Begin(menuName, closebtn, windowflags);
	}

	void EditorUI::EndMenu()
	{
		ImGui::End();
	}

	bool EditorUI::Button(const char* label, void(*onclickCallBack)(), float width, float height)
	{
		if (ImGui::Button(label, ImVec2(width, height)))
		{
			if (onclickCallBack != nullptr)
				onclickCallBack();
			return true;
		}
		return false;
	}

	void EditorUI::List(const char* label, const std::vector<Item*>& items, int* rPointer)
	{
		const char* names[20];
		int len = items.size();
		if (len > 20)
			len = 20;
		for (int i = 0; i < len; i++)
			names[i] = items[i]->GetName();
		ImGui::ListBox(label, rPointer, names, len, 10);
	}

	bool EditorUI::TopMenuBar()
	{
		return ImGui::BeginMainMenuBar();
	}

	void EditorUI::TopMenuBarEnd()
	{
		ImGui::EndMainMenuBar();
	}

	bool EditorUI::Menu(const char* label)
	{
		return ImGui::BeginMenu(label);
	}

	void EditorUI::MenuEnd()
	{
		ImGui::EndMenu();
	}

	void EditorUI::MenuOption(const char* label, bool* isSelected)
	{
		ImGui::MenuItem(label, NULL, isSelected);
	}

	void EditorUI::MenuOption(const char* label, void(*selectedCallBack)())
	{
		bool select = false;
		if (ImGui::MenuItem(label, NULL, &select))
		{
			selectedCallBack();
		}
	}

	void EditorUI::Separator(const char* label)
	{
		if (label == nullptr)
		{
			ImGui::Separator();
		}
		else
		{
			ImGui::SeparatorText(label);
		}
	}

	void EditorUI::SetBackground(int color)
	{
		if (color == 0)
		{
			ImGui::StyleColorsLight();
		}
		else if (color == 1)
		{
			ImGui::StyleColorsDark();
		}
		else if (color == 2)
		{
			ImGui::StyleColorsClassic();
		}
	}

	void EditorUI::OptionalButton(const char* label, const char* items, int* rPointer,
		void(*selectedCallback)(int index))
	{
		if (ImGui::Combo(label, rPointer, items))
		{
			if (selectedCallback != nullptr)
			{
				selectedCallback(*rPointer);
			}				
		}
	}

	bool EditorUI::Dialog(const char* label, bool* exist)
	{		
		if (!(*exist))
		{
			return false;
		}
		//EditorUI::NewMenu(label, 500.f, 300.f, 400.f, 200.f, true, false, exist);
		ImGuiWindowFlags windowflags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;

		ImGuiViewport* viewport = ImGui::GetMainViewport();
		ImVec2 pos = viewport->WorkPos;
		pos.x += 400;
		pos.y += 200;
		ImGui::SetNextWindowPos(pos);
		ImGui::SetNextWindowSize(ImVec2(500, 300));

		return ImGui::Begin(label, exist, windowflags);
	}

	void EditorUI::Text(const char* text)
	{
		ImGui::Text(text);
	}

	void EditorUI::Text(const char* text, float R, float G, float B, float A)
	{
		ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(R, G, B, A));
		ImGui::Text(text);
		ImGui::PopStyleColor();
	}

	void EditorUI::InputBox(const char* label, char* textBuf, unsigned int bufLen)
	{
		ImGui::InputText(label, textBuf, bufLen);
	}

	bool EditorUI::TreeNode(const char* title)
	{
		return ImGui::TreeNode(title);
	}

	void EditorUI::TreePop()
	{
		ImGui::TreePop();
	}

	void EditorUI::SliderFloat(const char* attrName, float* reference, float min, float max)
	{
		ImGui::SliderFloat(attrName, reference, min, max);
	}

	void EditorUI::SliderInt(const char* attrName, int* reference, int min, int max)
	{
		ImGui::SliderInt(attrName, reference, min, max);
	}

	void EditorUI::DragFloat(const char* attrName, float* reference, float min, float max)
	{
		ImGui::DragFloat(attrName, reference, 0.5f, min, max, "%.2f");
	}

	void EditorUI::SetSameLine()
	{
		ImGui::SameLine();
	}

	void EditorUI::ShowDemo()
	{
		ImGui::ShowDemoWindow();
	}

	void EditorUI::Viewport()
	{
		ImGuiViewport* viewport = ImGui::GetMainViewport();
		ImGui::SetNextWindowPos(viewport->WorkPos);
		ImGui::SetNextWindowSize(viewport->WorkSize);
		ImGui::SetNextWindowViewport(viewport->ID);
		ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
		ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 0.0f, 0.0f });
		ImGuiWindowFlags windowflags = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar |
			ImGuiWindowFlags_NoResize;

		ImGui::Begin("Viewport", (bool*)false, windowflags);
		ImGui::DockSpace(ImGui::GetID("MainDockSpace"), { 0, 0 }, ImGuiDockNodeFlags_PassthruCentralNode);
		ImGui::End();
		ImGui::PopStyleVar();
		ImGui::PopStyleVar();
	}

	void EditorUI::MessageArea()
	{
		ImGuiViewport* viewport = ImGui::GetMainViewport();
		ImVec2 pos = viewport->WorkPos;
		pos.x += 300;
		pos.y += 0;
		ImGui::SetNextWindowPos(pos);
		ImGui::SetNextWindowSize(ImVec2(200, 200));
		ImGuiWindowFlags windowflags = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoResize |
			ImGuiWindowFlags_NoTitleBar |
			ImGuiWindowFlags_NoDocking;
		ImGui::Begin("MessageArea", (bool*)0, windowflags);
	}

}